from PySide6.QtWidgets import (
    QApplication,
    QWidget,
    QLineEdit,
    QPushButton,
    QHBoxLayout,
    QListWidget,
    QVBoxLayout,
    QListWidgetItem,
    QCheckBox, QMenu,
    QSizePolicy
)
from PySide6.QtCore import Qt, QPoint,QSize
from PySide6.QtGui import QAction,QIcon
from uuid import uuid4
from dataclasses import dataclass
from typing import List,Callable
import sys


@dataclass
class Task:
    id: str
    text: str
    done: bool = False


class TaskItem(QWidget):
    def __init__(self, task: Task,on_delete:Callable[[],None]):
        super().__init__()
        icon = QIcon.fromTheme("edit-delete")
        self.on_delete = on_delete
        self._rm_btn = QPushButton()
        self._rm_btn.setIcon(icon)
        self._rm_btn.setFixedWidth(30)
        self._rm_btn.clicked.connect(self.on_delete)
        self.task = task
        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        self._checkbox = QCheckBox(task.text)
        self._checkbox.setChecked(task.done)
        self._checkbox.stateChanged.connect(self.on_stage_changed)
        font = self._checkbox.font()
        self._checkbox.setFont(font)
        self.update_strike()
        layout.addWidget(self._checkbox)
        layout.addWidget(self._rm_btn)
        self.setLayout(layout)

    def on_stage_changed(self, stage: int):
        self.task.done = (stage == 2)
        self.update_strike()

    def update_strike(self):
        font = self._checkbox.font()
        font.setStrikeOut(self.task.done)
        self._checkbox.setFont(font)


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.tasks: List[Task] = []
        self.setWindowTitle("Todo")
        self._input = QLineEdit()
        self._input.setPlaceholderText("Enter a todo")
        self._add_btn = QPushButton("Add")
        self._add_btn.clicked.connect(self.add_task)
        top = QHBoxLayout()
        top.addWidget(self._input)
        top.addWidget(self._add_btn)
        self._search = QLineEdit()
        self._search.setPlaceholderText("Search")
        self._search.textChanged.connect(self.refresh_list)
        self._list = QListWidget()
        mid = QHBoxLayout()
        mid.addWidget(self._search)
        root = QVBoxLayout()
        root.addLayout(top)
        root.addLayout(mid)
        root.addWidget(self._list)
        self.setLayout(root)

    def add_task(self):
        text = self._input.text().strip()
        if not text:
            return
        self._add_raw_task(text)
        self._input.clear()

    def _add_raw_task(self, text: str):
        tid = str(uuid4())
        self.tasks.append(Task(tid, text))
        self.refresh_list()

    def refresh_list(self):
        self._list.clear()
        keyword = self._search.text().strip().lower()
        for task in self.tasks:
            if keyword in task.text.lower():
                delete_callback = lambda: self.delete_task(task)
                item_widget = TaskItem(task,delete_callback)
                list_item = QListWidgetItem()
                self._list.addItem(list_item)
                self._list.setItemWidget(list_item, item_widget)
    def delete_task(self,task:Task):
        self.tasks = [t for t in self.tasks if t.id != task.id]
        self.refresh_list()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec())
